package com.gbei.center.oauth.service.impl;

import com.gbei.center.model.OpenResource;
import com.gbei.center.model.OpenResourceApp;
import com.gbei.center.oauth.mapper.AuthAccessTokenMapper;
import com.gbei.center.oauth.mapper.OpenResourceAppMapper;
import com.gbei.center.oauth.mapper.OpenResourceMapper;
import com.gbei.center.oauth.model.AuthAccessToken;
import com.gbei.center.oauth.req.ReqUserToken;
import com.gbei.center.oauth.service.ApiService;
import com.gbei.center.req.open.ReqAreaCode;
import com.gbei.center.req.open.ReqThirdpartyPlaceOrder;
import com.gbei.center.req.open.ReqUserCommon;
import com.gbei.center.utils.ArrayUtil;
import com.gbei.center.utils.JsonUtils;
import com.gbei.center.utils.RestTemplateClient;
import com.gbei.center.utils.message.ResponseInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @Discription ${在此输入一句话描述此文件的作用}
 * @Author yang jun
 * @Date 2019/5/23 11:58
 */
@Service
public class ApiServiceImpl implements ApiService{

    @Autowired
    private OpenResourceAppMapper openResourceAppMapper;
    @Autowired
    private OpenResourceMapper openResourceMapper;
    @Autowired
    private RestTemplateClient restTemplateClient;
    @Autowired
    private AuthAccessTokenMapper authAccessTokenMapper;


    /**
     * 用户根据openId获取京贝尔系统的微信token
     * @param req
     * @return
     */
    @Override
    public String getUserToken(ReqUserToken req,String apiUrl){
        //根据token查询记录
        AuthAccessToken authAccessToken = authAccessTokenMapper.selectByAccessToken(req.getToken());
        String openAppId = authAccessToken.getClientId();
        //判断接口权限
        if (!checkApiScope(apiUrl,openAppId)){
            return JsonUtils.toJson(ResponseInfo.LACK_API_SCOPE.messageToResult());
        }
        Map<String,String> map = new HashMap<>();
        map.put("openId",req.getWxOpenId());

        //调用第三方平台接口
        String result = restTemplateClient.common(map,"http://thirdparty/user/getAccessToken");
        return result;
    }


    /**
     * 用户授权登录获取用户信息
     * @param req
     * @return
     */
    @Override
    public String getUserInfo(ReqUserCommon req){
        //查询数据库中的Access Token
        AuthAccessToken authAccessToken = authAccessTokenMapper.selectByAccessToken(req.getToken());
        if (authAccessToken.getGrantType().equals("authorization_code")){
            req.setUserMobile(authAccessToken.getMobile());
            req.setOpenAppId(authAccessToken.getClientId());
            Map<String,String> actionMap = new HashMap<>();
            actionMap.put("select","userName,userNickName,userHeadFile,userEmail");
            req.setScope(JsonUtils.toJson(actionMap));
            Map<String,Object> map = new HashMap<>();
            map.put("userName","");
            map.put("userNickName","");
            map.put("userHeadFile","");
            map.put("userEmail","");
            req.setExtraInfo(JsonUtils.toJson(map));
            //调用第三方平台接口
            String result = restTemplateClient.getUserInfo(req);
            return result;
        }else {
            return JsonUtils.toJson(ResponseInfo.FAILURE.toResult("token不存在用户信息"));
        }
    }

    /**
     * 开放平台注册用户
     * @param req
     * @return
     */
    @Override
    public String userCommon(ReqUserCommon req,String apiUrl) {
        if (!StringUtils.isNoneBlank(req.getUserMobile())){
            return JsonUtils.toJson(ResponseInfo.FAILURE.toResult("userMobile 不能为空"));
        }
        //根据token查询记录
        AuthAccessToken authAccessToken = authAccessTokenMapper.selectByAccessToken(req.getToken());
        String openAppId = authAccessToken.getClientId();
        req.setOpenAppId(openAppId);
        //判断接口权限
        if (!checkApiScope(apiUrl,openAppId)){
            return JsonUtils.toJson(ResponseInfo.LACK_API_SCOPE.messageToResult());
        }

        //查找应用对接口的操作的字段
        Map<String,String> actionMap = new HashMap<>();
        actionMap.put("insert",checkApiScope(apiUrl,openAppId,"insert"));
        actionMap.put("update",checkApiScope(apiUrl,openAppId,"update"));
        actionMap.put("delete",checkApiScope(apiUrl,openAppId,"delete"));
        actionMap.put("select",checkApiScope(apiUrl,openAppId,"select"));

        req.setScope(JsonUtils.toJson(actionMap));

        //查找应用对接口的字段权限
        String fieldScope = checkApiScope(apiUrl,openAppId,"");

        if (StringUtils.isNoneBlank(req.getExtraInfo())){
            Map<String,Object> map = JsonUtils.fromJson(req.getExtraInfo(),Map.class);
            //根据客户的权限更新扩展字段
            req.setExtraInfo(JsonUtils.toJson(getMap(map,fieldScope)));
        }

        //调用第三方平台接口
        String result = restTemplateClient.getUserInfo(req);
        return result;
    }

    /**
     * 会员相关获取新的map
     * @param map
     * @param fieldScope
     * @return
     */
    public Map<String,Object> getMap(Map<String,Object> map, String fieldScope) {

        //应用对接口的字段没有权限
        if (!StringUtils.isNoneBlank(fieldScope)){
            Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator();
            while(it.hasNext()){
                Map.Entry<String, Object> entry = it.next();
                //去除以user或order开头的键值对 留下客户的私有字段
                if(entry.getKey().startsWith("user") || entry.getKey().startsWith("order")){
                    it.remove();//使用迭代器的remove()方法删除元素
                }
            }
            return map;
        }else {
            Map<String,Object> resultMap = new HashMap<>();
            List<String> list = Arrays.asList(fieldScope.split(","));
            for (String s : list){
                Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator();
                while(it.hasNext()){
                    Map.Entry<String, Object> entry = it.next();
                    //保存有权限的字段 和 客户的私有字段
                    if(entry.getKey().equals(s) || !entry.getKey().startsWith("user") || !entry.getKey().startsWith("order")){
                        resultMap.put(entry.getKey(),entry.getValue());
                    }
                }
            }
            return resultMap;
        }
    }

    /**
     * 第三方下单/修改/查询/退款
     * @param req
     * @return
     */
    @Override
    public String placeOrder(ReqThirdpartyPlaceOrder req,String apiUrl){
        //根据token查询记录
        AuthAccessToken authAccessToken = authAccessTokenMapper.selectByAccessToken(req.getToken());
        String openAppId = authAccessToken.getClientId();
        req.setOpenAppId(openAppId);
        //判断接口权限
        if (!checkApiScope(apiUrl,openAppId)){
            return JsonUtils.toJson(ResponseInfo.LACK_API_SCOPE.messageToResult());
        }

        //查找应用对接口的操作的字段
        Map<String,String> actionMap = new HashMap<>();
        actionMap.put("insert",checkApiScope(apiUrl,openAppId,"insert"));
        actionMap.put("update",checkApiScope(apiUrl,openAppId,"update"));
        actionMap.put("delete",checkApiScope(apiUrl,openAppId,"delete"));
        actionMap.put("select",checkApiScope(apiUrl,openAppId,"select"));

        req.setScope(JsonUtils.toJson(actionMap));

        //查找应用对接口的字段权限
        String fieldScope = checkApiScope(apiUrl,openAppId,"");

        if (StringUtils.isNoneBlank(req.getExtraInfo())){
            Map<String,Object> map = JsonUtils.fromJson(req.getExtraInfo(),Map.class);
            //应用没有这个接口的字段权限
            if (!StringUtils.isNoneBlank(fieldScope)){
                req.setExtraInfo("");
            }else {
                //根据客户的权限更新扩展字段
                req.setExtraInfo(JsonUtils.toJson(getMap(map,fieldScope)));
            }
        }

        //调用第三方平台接口
        String result = restTemplateClient.orderCommon(req);
        return result;

    }

    /**
     * 获取新的map
     * @param map
     * @param fieldScope
     * @return
     */
    public Map<String,Object> getNewMap(Map<String,Object> map, String fieldScope) {
        Map<String,Object> resultMap = new HashMap<>();
        List<String> list = Arrays.asList(fieldScope.split(","));
        for (String s : list){
            Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator();
            while(it.hasNext()){
                Map.Entry<String, Object> entry = it.next();
                //保存有权限的字段
                if(entry.getKey().equals(s) ){
                    resultMap.put(entry.getKey(),entry.getValue());
                }
            }
        }
        return resultMap;
    }


    /**
     * 第三方获取行政区域编码
     * @param req
     * @return
     */
    @Override
    public String getAreaCode(ReqAreaCode req,String apiUrl){
        //根据token查询记录
        AuthAccessToken authAccessToken = authAccessTokenMapper.selectByAccessToken(req.getToken());
        String openAppId = authAccessToken.getClientId();
        //判断接口权限
        if (!checkApiScope(apiUrl,openAppId)){
            return JsonUtils.toJson(ResponseInfo.LACK_API_SCOPE.messageToResult());
        }

        //查找应用对接口的操作权限
        //查找应用对接口的操作的字段
        Map<String,String> actionMap = new HashMap<>();
        actionMap.put("insert",checkApiScope(apiUrl,openAppId,"insert"));
        actionMap.put("update",checkApiScope(apiUrl,openAppId,"update"));
        actionMap.put("delete",checkApiScope(apiUrl,openAppId,"delete"));
        actionMap.put("select",checkApiScope(apiUrl,openAppId,"select"));

        req.setScope(JsonUtils.toJson(actionMap));

        //查找应用对接口的字段权限
        String fieldScope = checkApiScope(apiUrl,openAppId,"");

        if (StringUtils.isNoneBlank(req.getExtraInfo())){
            Map<String,Object> map = JsonUtils.fromJson(req.getExtraInfo(),Map.class);
            //应用没有这个接口的扩展字段权限
            if (!StringUtils.isNoneBlank(fieldScope)){
                req.setExtraInfo("");
            }else {
                //根据客户的权限更新扩展字段
                req.setExtraInfo(JsonUtils.toJson(getNewMap(map,fieldScope)));
            }
        }

        //调用第三方平台接口
        String result = restTemplateClient.areaCommon(req);
        return result;
    }

    /**
     * 判断应用是否有这个api的权限
     * @param apiUrl
     * @param openAppId
     * @return
     */
    public boolean checkApiScope(String apiUrl,String openAppId){
        OpenResource openResource = openResourceMapper.getOpenResourceByName(apiUrl);
        if (openResource != null){
            OpenResourceApp openResourceApp = openResourceAppMapper.getOpenResourceApp(openAppId, openResource.getResourceId());
            if (openResourceApp != null){
                return true;
            }
        }
        return false;
    }

    /**
     * 根据条件查找应用在这个接口中的已申请的字段，及操作的字段
     * @param apiUrl
     * @param openAppId  应用ID
     * @param action  insert,update,delete,select
     * @return
     */
    public String checkApiScope(String apiUrl,String openAppId,String action){
        OpenResource openResource = openResourceMapper.getOpenResourceByName(apiUrl);
        if (openResource != null){
            List<OpenResource> openResources;
            if (!StringUtils.isNoneBlank(action)){
                //查找这个接口有权限的字段
                openResources = openResourceMapper.listOpenResource(openAppId, openResource.getResourceId());
            }else {
                //查找这个接口操作的权限
                openResources = openResourceMapper.listOpenResourceByAction(openAppId, openResource.getResourceId(),action);
            }

            if (ArrayUtil.isNotBlank(openResources)){
                StringBuffer result = new StringBuffer();
                for (int i = 0; i < openResources.size(); i++) {
                    OpenResource open = openResources.get(i);
                    if (i == openResources.size() - 1){
                        result.append(open.getEnName());
                    }else {
                        result.append(open.getEnName() + ",");
                    }
                }
                return result.toString();
            }
        }
        return null;
    }


}
